#pragma once

#include "pbcxx.h"
#include "json.hpp"
#include "utils.h"
#include <string>
#include <vector>
#include <cstdlib>
#include <ctime>
#include <unordered_set>

class BMapAcc {
    ele_class g_;
    ele_class s_;
public:
    BMapAcc(ele_class g, ele_class s): g_(g), s_(s) {}

    template<class T>
    ele_class operator()(T container);

    template<class T>
    ele_class operator()(T container_begin, int cnt);
};

template<class T>
ele_class BMapAcc::operator()(T container) {
    return (*this)(container.begin(), container.size());
}

template<class T>
ele_class BMapAcc::operator()(T container_begin, int cnt) {
    ele_class res(g_);
    ele_class exp(s_);
    exp = 1;
    auto it_end = container_begin + cnt;
    for (auto it = container_begin; it != it_end; ++it) {
        exp = exp * ((*it) + s_);
    }
    return res ^ exp;
}


void VEDBSetup(nlohmann::json& vedbJson);

void setSearchWords(nlohmann::json& vedbJson, int num);

void TokenGen(nlohmann::json& vedbJson);

void Search(nlohmann::json& vedbJson);

void Verify(nlohmann::json& vedbJson);